package com.lw.sbdemo2.common.web.returnhandle;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.lw.sbdemo2.common.vo.ResultModel;
import com.lw.sbdemo2.common.web.anno.ResultModelAnnotation;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>标题: 返回ResultModel处理</p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: chenweibin
 * @date 2018/3/17
 */
public class ResultModelHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler {

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResultModelAnnotation.class) ||
                returnType.hasMethodAnnotation(ResultModelAnnotation.class));
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
        ResultModel<Object> resultModel;
        ApiOperation methodAnnotation = returnType.getMethodAnnotation(ApiOperation.class);
        String message = "";
        if (methodAnnotation != null) {
            message = methodAnnotation.value() + "成功";
        }

        if (returnValue instanceof ResultModel) {
            resultModel = (ResultModel<Object>) returnValue;
            if (!resultModel.isSuccess()) {
                resultModel.setMessage(message + "error");
            }
        } else {
            resultModel = ResultModel.success(returnValue, message);
        }
        mavContainer.setRequestHandled(true);
        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        // 设置状态码
        response.setStatus(HttpStatus.OK.value());
        response.setHeader("result-model", "true");
        // 设置ContentType
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        // 避免乱码
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.write(JSON.toJSONString(resultModel, SerializerFeature.WriteMapNullValue));
            writer.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

}
